package com.luxoft.scoremanager.server.service.impl;

import com.luxoft.scoremanager.server.dao.ComponentDao;
import com.luxoft.scoremanager.server.dao.ComponentValuesDao;
import com.luxoft.scoremanager.server.dao.ScorePackageDao;
import com.luxoft.scoremanager.server.dao.StaticDataDao;
import com.luxoft.scoremanager.server.model.web.Component;
import com.luxoft.scoremanager.server.model.web.ScorePackage;
import com.luxoft.scoremanager.server.model.web.StaticData;
import com.luxoft.scoremanager.server.model.dao.ScorePackageDaoModel;
import com.luxoft.scoremanager.server.model.dao.StaticDataDaoModel;
import com.luxoft.scoremanager.server.model.dao.ComponentValuesDaoModel;
import com.luxoft.scoremanager.server.model.dao.ComponentDaoModel;
import com.luxoft.scoremanager.server.service.PackageManagerService;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;

/**
 * Created by Александр on 22.09.13.
 */

public class BasicPackageManagerService implements PackageManagerService {

    private final  ComponentDao componentDao ;
    private final  ScorePackageDao scorePackageDao;
    private final  StaticDataDao staticDataDao;
    private final  ComponentValuesDao componentValuesDao;


    public BasicPackageManagerService(ComponentDao componentDao,ScorePackageDao scorePackageDao, StaticDataDao staticDataDao, ComponentValuesDao componentValuesDao) {
        this.componentDao = componentDao;
        this.scorePackageDao = scorePackageDao;
        this.staticDataDao = staticDataDao;
        this.componentValuesDao = componentValuesDao;
    }


    @Override
    public void addComponentToScorePackage(Integer id, Component component) {
        checkArgument(id != null, "id should be provided");
        checkArgument(component != null, "component should be provided");

        ComponentValuesDaoModel componentValuesDaoModel = new ComponentValuesDaoModel(component);
        componentValuesDaoModel.setScorePackageDao(scorePackageDao.getById(id));
        componentValuesDao.addComponentValues(componentValuesDaoModel);
    }

    @Override
    public void deleteComponentFromScorePackage(Integer id, Component component) {
        checkArgument(id != null, "id should be provided");
        checkArgument(component != null, "component should be provided");
        checkArgument(component.getId() != null, "component id should be provided");
        ComponentValuesDaoModel componentValuesDaoModel = new ComponentValuesDaoModel(component);
        componentValuesDaoModel.setScorePackageDao(scorePackageDao.getById(id));
        componentValuesDao.deleteComponentValues(componentValuesDaoModel);

    }

    @Override
    public void updateComponentList(Integer id, List<Component> componentList) {
        checkArgument(componentList != null, "component should be provided");
        for (Component component:componentList){
            checkArgument(component != null, "component should be provided");
            checkArgument(component.getId() != null, "component id should be provided");
            ComponentValuesDaoModel componentValuesDaoModel = new ComponentValuesDaoModel(component);
            componentValuesDaoModel.setScorePackageDao(scorePackageDao.getById(id));
            componentValuesDao.updateComponentValues(componentValuesDaoModel);
        }
    }

    @Override
    public void updateComponent(Integer id,Component component) {
        checkArgument(component != null, "component should be provided");
        checkArgument(component.getId() != null, "component id should be provided");
        ComponentValuesDaoModel componentValuesDaoModel = new ComponentValuesDaoModel(component);
        componentValuesDaoModel.setScorePackageDao(scorePackageDao.getById(id));
        componentValuesDao.updateComponentValues(componentValuesDaoModel);
    }

    @Override
    public void updateScorePackage(ScorePackage scorePackage) {
        checkArgument(scorePackage != null, "score package should be provided");
        checkArgument(scorePackage.getId() != null, "score package id should be provided");
        ScorePackageDaoModel scorePackageDaoModel = scorePackageDao.getById(scorePackage.getId());
        scorePackageDaoModel.setStage(scorePackage.getStage());
        scorePackageDao.updatePackage(scorePackageDaoModel);
        if (scorePackage.getComponents().size() > 1) {
            this.updateComponentList(scorePackage.getId(),scorePackage.getComponents());
        }
        else if (scorePackage.getComponents().size() == 1) {
            this.updateComponent(scorePackage.getId(),scorePackage.getComponents().get(0));
        }
    }

    @Override
    public ScorePackage getScorePackageById(Integer id) {
        checkArgument(id != null, "id should be provided");
        ScorePackageDaoModel scorePackageDaoModel = scorePackageDao.getById(id);
        List<StaticDataDaoModel> staticDataDaoModelList =  staticDataDao.getAll();
        ScorePackage scorePackage = new ScorePackage(scorePackageDaoModel,staticDataDaoModelList);
        return  scorePackage;
    }

    @Override
    public List<Component> getAllComponentByIdOfScorePackage(Integer id) {
        checkArgument(id != null, "id should be provided");
        List<ComponentValuesDaoModel> componentValuesDaoModelList = componentValuesDao.getAllForPackage(id);
        List<Component> componentList = new ArrayList<Component>();
        for (ComponentValuesDaoModel componentValuesDaoModel:componentValuesDaoModelList){
            componentList.add(new Component(componentValuesDaoModel));
        }
        return componentList;
    }

    @Override
    public List<Component> getAllComponentByScorePackage(ScorePackage scorePackage) {
        checkArgument(scorePackage != null, "score package should be provided");
        checkArgument(scorePackage.getId() != null, "score package id should be provided");
        List<ComponentValuesDaoModel> componentValuesDaoModelList = componentValuesDao.getAllForPackage(scorePackage.getId());
        List<Component> componentList = new ArrayList<Component>();
        for (ComponentValuesDaoModel componentValuesDaoModel:componentValuesDaoModelList){
            componentList.add(new Component(componentValuesDaoModel));
        }
        return componentList;
    }

    @Override
    public List<StaticData> getAllStaticData() {
        List<StaticDataDaoModel> staticDataDaoModelList = staticDataDao.getAll();
        List<StaticData> staticDataList = new ArrayList<StaticData>();
        for (StaticDataDaoModel staticDataDaoModel:staticDataDaoModelList){
            staticDataList.add(new StaticData(staticDataDaoModel));
        }
        return staticDataList;
    }
}
